<template>
  <div style="height: 100%;">
    <div class="x6-box-group">
      <div class="x6-left-group">
        <div class="relat-graph-box" ref="relatGraphBox"></div>
        <div class="tip">
          <span class="type0"></span>数据线
          <span class="type1"></span>状态线
          <span class="type2"></span>控制线
        </div>
      </div>

      <div class="x6class-info-group">
        <div class="info" v-if="nodeShow">
          <div class="title main-title">组件 {{ pName }} 信息详情</div>
          <div class="infoBody" v-if="pluginsInfo.pfunctionList">
            <div class="title">函数信息</div>
            <div class="infodata">
              <div class="infodata-item-group"
                   v-for="(item, index) in pluginsInfo.pfunctionList"
                   :key="index">
                <div class="infodata-item">
                  <div class="infodata-label">函数名：</div>
                  <div>{{ item.functionName }}</div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">入参类型：</div>
                  <div>{{ item.paramInputClass }}</div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">入 参 值：</div>
                  <div>{{ item.text }}</div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">出参类型：</div>
                  <div>{{ item.paramOutputClass }}</div>
                </div>
              </div>
            </div>
          </div>

          <div class="infoBody" v-if="pluginsInfo.parequire">
            <div class="title">环境信息</div>
            <div class="infodata">
              <div class="infodata-item-group">
                <div class="infodata-item">
                  <div class="infodata-label">最小CPU：</div>
                  <div>{{ pluginsInfo.parequire.requireCPU }}</div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">最小GPU：</div>
                  <div>{{ pluginsInfo.parequire.requireGPU }}</div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">最小存储：</div>
                  <div>{{ pluginsInfo.parequire.requireDisk }}</div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">运行内存：</div>
                  <div>{{ pluginsInfo.parequire.requireMemory }}</div>
                </div>
              </div>
            </div>
          </div>
          <div class="infoBody" v-if="pluginsInfo.pamonitor">
            <div class="title">配置信息</div>
            <div class="infodata">
              <div class="infodata-item-group">
                <div class="infodata-item">
                  <div class="infodata-label">监控频率：</div>
                  <div>{{ pluginsInfo.pamonitor.monitorRate }}</div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">监控频率：</div>
                  <div>
                    <span v-if="pluginsInfo.pamonitor.monitorType === 0">进程监控</span>
                    <span v-else-if="pluginsInfo.pamonitor.monitorType === 1">进程监控</span>
                    <span v-else>全部</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="infoBody" v-if="pluginsInfo.paswitch">
            <div class="title">切换信息</div>
            <div class="infodata">
              <div class="infodata-item-group">
                <div class="infodata-item">
                  <div class="infodata-label">切换名称：</div>
                  <div>{{ pluginsInfo.paswitch.switchName }}</div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">切换地址：</div>
                  <div>{{ pluginsInfo.paswitch.switchAddress }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="info" v-if="lineShow">
          <div class="title">连线关系详情</div>
          <div class="infoBody" v-if="lineInfo">
            <div class="infodata">
              <div class="infodata-item-group"
                   v-for="(item, index) in lineInfo"
                   :key="index">
                <div class="infodata-item">
                  <div class="infodata-label">线类型：</div>
                  <div>
                    <span v-if="item.relationLineType===0">数据线</span>
                    <span v-else-if="item.relationLineType===1">状态线</span>
                    <span v-else>控制线</span>
                  </div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">输出类型：</div>
                  <div>
                    <span v-if="item.relationOutType===0">单值</span>
                    <span v-else-if="item.relationOutType===1">JSON</span>
                    <span v-else>结构体</span>
                  </div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">源函数：</div>
                  <div>{{ item.SName }}</div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">目标函数：</div>
                  <div>{{ item.TName }}</div>
                </div>
                <div class="infodata-item">
                  <div class="infodata-label">出参位置：</div>
                  <div>{{ item.relationLineInputIndex }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {Graph, Edges, Shape, Addon, NodeView} from "@antv/x6";
import {get_getAppliesInfo} from "@/apis/appLC/applc";
import {
  get_selectPFunctionByPluginsId,
  get_getAppLineInfo,
} from "@/apis/comList/comList";

let relatGraph = null

export default {
  name: "RelatGraph",
  props: {
    appid: {
      type: [String, Number],
      default: ''
    }
  },
  data() {
    return {
      pName: "",
      lineInfo: "",
      nodeShow: false,
      lineShow: false,
      pluginsInfo: {
        pfunctionList: "",
        parequire: "",
        paswitch: "",
        pamonitor: "",
      },
    }
  },
  watch: {
    appid: {
      deep: true,
      handler: function (val) {
        this.appInfo(val)
      }
    }
  },
  mounted() {
    this.initX6()
  },
  methods: {
    // 初始化渲染x6
    initX6() {
      relatGraph = new Graph({
        container: this.$refs.relatGraphBox,
        autoResize: true, // 是否监听容器大小改变，并自动更新画布大小
        background: {
          // color: "#F5F6FA",
        },
        mousewheel: true, //鼠标轮滚缩放
        panning: true, //支持平移拖拽
        snapline: true, //对齐线
        interacting: false
      });
      relatGraph.centerContent();
      relatGraph.zoom(-0.8);
      relatGraph.on("edge:dblclick", (e) => {
        get_getAppLineInfo({
          lineId: e.cell.labels[0].attrs.labelText.lId,
        }).then((res) => {
          let {data} = res.data;
          data.forEach((item) => {
            item.funtionList.forEach((tem) => {
              if (item.relationLineSource == tem.id) {
                item.SName = tem.functionName;
              }
              if (item.relationLineTarget == tem.id) {
                item.TName = tem.functionName;
              }
            });
          });
          this.nodeShow = false;
          this.lineShow = true;
          this.lineInfo = data;
        });
      });
      relatGraph.on("node:dblclick", (e) => {
        this.pName = e.cell.label;
        get_selectPFunctionByPluginsId({pluginsId: e.cell.id}).then((res) => {
          let {data} = res.data;
          this.nodeShow = true;
          this.lineShow = false;
          data.pfunctionList.forEach((item) => {
            let arr = item.paramInputClass.split(",");
            arr.forEach((text, index) => {
              arr[index] = "被占用";
            });
            item.adataList.forEach((tem) => {
              if (item.id == tem.ftId) {
                arr[tem.aindex] = tem.avalue;
              }
            });
            item.text = arr.join(",");
          });
          this.pluginsInfo = data;
        });
      });
    },
    // 应用详情
    appInfo(appId) {
      this.appId = appId;
      this.appInfoData = {
        nodes: [],
        edges: [],
      };
      get_getAppliesInfo({appId}).then((res) => {
        let {data} = res.data;
        this.appinfoList = data.applies;
        this.appinfoList.addTime = this.$moment(
          this.appinfoList.addTime
        ).format("YYYY-MM-DD");
        if (this.appinfoList.editTime) {
          this.appinfoList.editTime = this.$moment(
            this.appinfoList.editTime
          ).format("YYYY-MM-DD");
        }
        this.appinfoListRequire = data.parequire;
        this.appinfoListSwitch = data.paswitch;
        this.appinfoListMonitor = data.pamonitor;
        //获取源id与目标id数组去重
        let nodeId = [];
        if (data.arelation.length > 0) {
          data.arelation.forEach((item) => {
            this.appInfoData.edges.push({
              source: item.relationLineSource,
              target: item.relationLineTarget,
              labels: [
                {
                  markup: [
                    {
                      tagName: "rect",
                      selector: "labelBody",
                    },
                    {
                      tagName: "text",
                      selector: "labelText",
                    },
                  ],
                  attrs: {
                    labelText: {
                      text: " ",
                      lId: item.relationLineId,
                    },
                    labelBody: {
                      ref: "labelText",
                      refY: 3,
                      refWidth: 4,
                      refHeight: -6,
                      fill: item.relationLineType === 0 ? "#267ff7" : item.relationLineType === 1 ? "#45D9BF" : "#fd9f6c",
                    },
                  },
                  position: item.relationLineType === 0 ? 0.46 : item.relationLineType === 1 ? 0.5 : 0.54,
                },
              ],
              attrs: {
                line: {
                  stroke: '#ffffff',
                },
                body: {
                  fill: '#f5f5f5'
                },
              }

            });
            nodeId.push(item.relationLineSource);
            nodeId.push(item.relationLineTarget);
          });
          nodeId = Array.from(new Set(nodeId));
          let nodeInfo = {};
          let arr = [];
          nodeId.forEach((item) => {
            nodeInfo[item] = "";
            arr.push(
              data.arelation.find((res) => {
                return (
                  item == res.relationLineSource || item == res.relationLineTarget
                );
              })
            );
          });
          arr.forEach((item) => {
            if (!nodeInfo[item.relationLineSource]) {
              nodeInfo[item.relationLineSource] = {
                id: item.relationLineSource, // String，可选，节点的唯一标识
                x: item.relationLineSourceXaxis, // Number，必选，节点位置的 x 值
                y: item.relationLineSourceYaxis, // Number，必选，节点位置的 y 值
                width: 160, // Number，可选，节点大小的 width 值
                height: 60, // Number，可选，节点大小的 height 值
                label: item.sourcePluginsName, // String，节点标签
              };
            }
            if (!nodeInfo[item.relationLineTarget]) {
              nodeInfo[item.relationLineTarget] = {
                id: item.relationLineTarget, // String，可选，节点的唯一标识
                x: item.relationLineTargetXaxis, // Number，必选，节点位置的 x 值
                y: item.relationLineTargetYaxis, // Number，必选，节点位置的 y 值
                width: 160, // Number，可选，节点大小的 width 值
                height: 60, // Number，可选，节点大小的 height 值
                label: item.targetPluginsName, // String，节点标签
              };
            }
          });
          for (const key in nodeInfo) {
            this.appInfoData.nodes.push(nodeInfo[key]);
          }
          this.pName = this.appInfoData.nodes[1].label;

          get_selectPFunctionByPluginsId({
            pluginsId: this.appInfoData.nodes[1].id,
          }).then((res) => {
            let {data} = res.data;
            data.pfunctionList.forEach((item) => {
              let arr = item.paramInputClass.split(",");
              arr.forEach((text, index) => {
                arr[index] = "被占用";
              });
              item.adataList.forEach((tem) => {
                if (item.id == tem.ftId) {
                  arr[tem.aindex] = tem.avalue;
                }
              });
              item.text = arr.join(",");
            });
            this.pluginsInfo = data;
          });
        }
        this.appInfoVisble = true;

        if (relatGraph) {
          relatGraph.fromJSON(this.appInfoData);
          this.nodeShow = true
        }
      });
    }
  }
}
</script>

<style scoped lang="less">
  .x6-box-group {
    width: 100%;
    height: 100%;
    display: flex;
  }

  .x6-left-group {
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    overflow: hidden;

    .tip {
      position: absolute;
      top: 0;
      right: 0;
      color: #ffffff;
      background-color: rgba(0, 0, 0, 0.3);
      padding: 5px 10px;

      span {
        display: inline-block;
        width: 8px;
        height: 8px;
        border-radius: 2px;
        margin-right: 5px;
      }

      .type0 {
        background: #267ff7;
      }

      .type1 {
        background: #45d9bf;
      }

      .type2 {
        background: #fd9f6c;
      }
    }


    .relat-graph-box {
      /*width: 100%;*/
      /*height: 100%;*/
      flex: 1;
    }
  }

  .x6class-info-group {
    width: 230px;
    flex-shrink: 0;

    .info {
      width: 230px;
      height: 100%;
      color: #fff;
      display: flex;
      flex-direction: column;

      .main-title {
        flex-shrink: 0;
      }

      .infoBody {
        flex: 1;
        display: flex;
        flex-direction: column;
        overflow: hidden;

        & > .title {
          margin-top: 2px;
        }
      }


      .title {
        background: #29d;
        width: 100%;
        height: 30px;
        padding-left: 5px;
        color: #fff;
        flex-shrink: 0;
        display: flex;
        align-items: center;
        justify-content: center;
      }


      .infodata {
        border: 1px solid #29d;
        height: 100%;
        overflow: hidden;
        overflow-y: auto;
        text-align: left;

        .infodata-item-group {
          border-bottom: 1px solid #29d;
          padding: 5px 0;
          font-size: 12px;

          &:last-child {
            border-bottom: none;
          }
        }

        .infodata-item {
          width: 100%;
          display: flex;
          padding: 5px 0;
        }

        .infodata-label {
          width: 80px;
          text-align: right;
          flex-shrink: 0;
        }
      }
    }
  }
</style>